package huu.phong.youtube;

import java.awt.MediaTracker;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;


public class Video implements Serializable{
	private static final long serialVersionUID = -1080772505347758185L;
	public String link;
	public String title;
	public String description;
	public Map<Format, String> originLink = new HashMap<Format, String>();
	public String viewCount;
	public String duration;
	public transient Format currentFormat;
	public String thumbnail;
	public Map<Integer, StoryBoard> storyBoards = new HashMap<Integer, StoryBoard>();
	public transient ImageIcon icon;
	public String username;
	public String userId;
	public boolean hd = false;
	
	public Video() {
	}

	public Video(String title, String link) {
		this.title = title;
		this.link = link;
	}

	public String getLink() {
		return link;
	}

	public void setLink(String link) {
		this.link = link;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
	
	private Format getFormat(String link){
		for (Format format : Format.values()){
			if (link.contains("itag=" + format.getItag())){
				return format;
			}
		}
		return null;
	}

	public String getOriginLink(Format format) throws IOException{
		String str = null;
		if (!originLink.isEmpty()){
			str = getDirectLink(format);
			if (Utils.isURLAvailable(str)) return str;
		}
		URL url = new URL("http://www.youtube.com/get_video_info?video_id=" + link + "&el=vevo");
		//"&el=detailpage&ps=default&eurl=&gl=US&hl=en"
		URLConnection connection = url.openConnection();
		BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
		while ((str = in.readLine()) != null) {
			originLink.clear();
			StringTokenizer token = new StringTokenizer(str, "&");
			while (token.hasMoreTokens()){
				str = token.nextToken();
				if (str.contains("url_encoded_fmt_stream_map=")){
					str = str.substring(27);
					originLink.putAll(getLinks(str));
//					str = URLDecoder.decode(str, "UTF-8").replaceAll("sig=", "signature=");
//					System.out.println(URLDecoder.decode(str, "UTF-8"));
				} else if(str.contains("adaptive_fmts=")){
					str = str.substring(14);
					originLink.putAll(getLinks(str));
//					str = URLDecoder.decode(str, "UTF-8");
//					System.out.println(URLDecoder.decode(str, "UTF-8"));
				} else if (str.contains("storyboard_spec=")){
					str = str.substring(16);
					str = URLDecoder.decode(str, "UTF-8");
					StringTokenizer storyboard = new StringTokenizer(str, "|");
					if (storyboard.hasMoreTokens()) thumbnail = storyboard.nextToken();
					str = thumbnail.replaceFirst("sb/.*jpg", "");
					if (storyboard.hasMoreTokens()) storyboard.nextToken();
					int i = 1;
					while (storyboard.hasMoreTokens()){
						storyBoards.put(i, new StoryBoard(link, storyboard.nextToken(), str, i));
						i++;
					}
				}
			}
		}
		in.close();
		return getDirectLink(format);
	}
	
	private Map<Format, String> getLinks(String encode) throws UnsupportedEncodingException{
		Map<Format, String> links = new HashMap<Format, String>();
		encode = URLDecoder.decode(encode, "UTF-8").replaceAll("sig=", "signature=");
		StringTokenizer urls = new StringTokenizer(encode, ",");
		while (urls.hasMoreTokens()){
			encode = getLink(urls.nextToken());
			links.put(getFormat(encode), encode);
		}
		return links;
	}
	
	private String getDirectLink(Format format){
		String str = originLink.get(format);
		if (str == null){
			for (Format fmt : Format.values()){
				if (format.compareTo(fmt) < 0 && Format.isSameType(format, fmt)){
					str = originLink.get(fmt);
					if (str != null){
						currentFormat = fmt;
						break;
					}
				}
			}
		} else {
			currentFormat = format;
		}
		return str;
	}
	
	public boolean equals(Object obj){
		if (obj instanceof Video){
			Video song = (Video) obj;
			if (song.getTitle().equals(title)) return true;
		}
		return false;
	}
	public String toString(){
		return "<html><div style='padding: 0px 0px 25px 0px;'><b>" + title + "</b><p>Lượt xem: " + viewCount + " | Upload bởi: " + username + "</p></div></html>";
	}
	
	public ImageIcon getImage(){
		if (icon == null){
			try {
				icon = new VideoImage("http://img.youtube.com/vi/" + link + "/default.jpg", duration, hd);
				if (icon.getImageLoadStatus() ==  MediaTracker.ERRORED){
					icon = new VideoImage(SongRenderer.DEFAULT_DETAIL_ALBUM_ART.getImage(), duration);
				}
			} catch (IOException e) {
				icon = SongRenderer.DEFAULT_DETAIL_ALBUM_ART;
			}
		}
		return icon;
	}
	
	public StoryBoard getStoryBoard(){
		StoryBoard storyBoard = null;
		for (int i = Configure.getInstance().qualitySoryBoard; i >= 0 && storyBoard == null ; i--){
			storyBoard = storyBoards.get(i);
		}
		return storyBoard;
	}
	
	
	private String getLink(String link) throws UnsupportedEncodingException{
		StringTokenizer keys = new StringTokenizer(link, "&");
		String ret = "";
		while (keys.hasMoreTokens()){
			String key = keys.nextToken();
			if (key.contains("url=")){
				key = URLDecoder.decode(key, "UTF-8");
				ret = key.substring(4) + ret;
			}else if(key.contains("signature=")){
				ret = ret + "&" + key;
			}
		}
		return ret;
	}	
}
